import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from imblearn.over_sampling import SMOTE

def encode_features(X):
    categorical_cols = X.select_dtypes(include=['object']).columns
    if not categorical_cols.empty:
        # 使用 OneHotEncoder 而不是 LabelEncoder 的原因：
        # OneHotEncoder 可以避免给分类特征赋予数值意义，防止模型误以为这些数字有大小关系。
        ohe = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
        X_encoded = ohe.fit_transform(X[categorical_cols])
        X_encoded_df = pd.DataFrame(X_encoded, columns=ohe.get_feature_names_out(categorical_cols))
        X = pd.concat([X.drop(columns=categorical_cols), X_encoded_df], axis=1)
    return X

def standardize(X):
    scaler = StandardScaler()
    return scaler.fit_transform(X)

def split_data(X, y):
    return train_test_split(X, y, test_size=0.2, random_state=42)

def apply_smote(X_train, y_train):
    smote = SMOTE(random_state=42)
    return smote.fit_resample(X_train, y_train)

def to_numpy_float32(data):
    if isinstance(data, pd.DataFrame) or isinstance(data, pd.Series):
        data = data.values
    return np.asarray(data, dtype=np.float32)
